package com.dt.common.validation.definition;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Map;

import com.dt.common.validation.annotation.DecimalMax;
import com.dt.common.validation.impl.DefaultValidationDefinition;
import com.dt.common.validation.itf.ConstraintValidation;
import com.dt.common.validation.itf.ValidationContext;

import lombok.Setter;

@Setter
public class DecimalMaxDefinition extends DefaultValidationDefinition {
	private BigDecimal maxValue;
	private boolean inclusive;

	public DecimalMaxDefinition() {
		this.name = DecimalMax.class.getSimpleName();
	}

	@Override
	protected void fillMsgInterpolatingParams(Map<String, String> params) {
		params.put("value", maxValue.toString());
	}

	static BigDecimal getCheckedValue(Object propertyValue) {
		if (propertyValue instanceof Number) {
			Number number = (Number) propertyValue;
			if (propertyValue instanceof BigDecimal) {
				return (BigDecimal) number;

			} else if (propertyValue instanceof BigInteger) {
				return new BigDecimal((BigInteger) number);

			} else {
				return new BigDecimal(number.doubleValue());

			}
		} else if (propertyValue instanceof String) {
			return new BigDecimal((String) propertyValue);
		}

		return null;
	}

	@Override
	public ConstraintValidation buildValidation() {

		return new ConstraintValidation() {

			@Override
			public boolean isValid(ValidationContext context, Object objectValue, Object propertyValue) {
				if (propertyValue == null) {
					return true;
				}

				try {
					BigDecimal checkedValue = getCheckedValue(propertyValue);
					if (checkedValue != null) {
						if (inclusive) {
							return checkedValue.compareTo(maxValue) <= 0;
						} else {
							return checkedValue.compareTo(maxValue) < 0;
						}
					}else{
						return false;
					}
				} catch (NumberFormatException e) {
					return false;
				}
			}

		};

	}

}
